#include "AABBMesh.h"
#include "VertexList.h"

AABBMesh::AABBMesh(DAEFloat3 corner1,DAEFloat3 corner2 ):m_Corner1(corner1),m_Corner2(corner2)
{
	m_World.SetAsIdentity();
	m_Bounds[0]=corner1;
	m_Bounds[1]=corner2;
	// position and color vertexlist

	// 8 vertices needed
	m_pVertexList = new VertexList(8);
	m_pVertexList->AddSemantic(POSITION,3);
	m_pVertexList->AddSemantic(COLOR,1);
	// corner1

	DAEFloat3 p1 (corner2.x, corner1.y, corner1.z);
	DAEFloat3 p2 (corner2.x, corner2.y, corner1.z);
	DAEFloat3 p3 (corner1.x, corner2.y, corner1.z);

	DAEFloat3 p4 (corner2.x, corner1.y , corner2.z);
	DAEFloat3 p5 (corner1.x, corner1.y , corner2.z);
	DAEFloat3 p6 (corner1.x, corner2.y , corner2.z);
	m_pVertexList->AddVertexData(0,POSITION,&corner1);
	m_pVertexList->AddVertexData(1,POSITION,&p1);
	m_pVertexList->AddVertexData(2,POSITION,&p2);
	m_pVertexList->AddVertexData(3,POSITION,&p3);
	m_pVertexList->AddVertexData(4,POSITION,&p5);
	m_pVertexList->AddVertexData(5,POSITION,&p4);
	m_pVertexList->AddVertexData(6,POSITION,&corner2);
	m_pVertexList->AddVertexData(7,POSITION,&p6);
	for (int i=0;i<8;i++)
		m_pVertexList->AddVertexData(i,COLOR,(float)0xffffffff);
	
	//m_pVertexBuffer = device->Compile(m_pVertexList);
	
	m_pLineList = new LineList(12);

	m_pLineList->AddIndexedLine(0,1);
	m_pLineList->AddIndexedLine(1,2);
	m_pLineList->AddIndexedLine(2,3);
	m_pLineList->AddIndexedLine(3,0);

	m_pLineList->AddIndexedLine(4,5);
	m_pLineList->AddIndexedLine(5,6);
	m_pLineList->AddIndexedLine(6,7);
	m_pLineList->AddIndexedLine(7,4);

	m_pLineList->AddIndexedLine(0,4);
	m_pLineList->AddIndexedLine(1,5);
	m_pLineList->AddIndexedLine(2,6);
	m_pLineList->AddIndexedLine(3,7);
}

AABBMesh::~AABBMesh(void)
{
	delete m_pVertexList;
	delete m_pLineList;
}

bool AABBMesh::HitTest(Ray& ray,float& distance,float t0, float t1)
{
	float tmin, tmax, tymin, tymax, tzmin, tzmax;
	tmin = (m_Bounds[ray.m_Sign[0]].x - ray.m_Origin.x) * ray.m_InvDirection.x;
	tmax = (m_Bounds[1-ray.m_Sign[0]].x - ray.m_Origin.x) * ray.m_InvDirection.x;
	tymin = (m_Bounds[ray.m_Sign[1]].y - ray.m_Origin.y) * ray.m_InvDirection.y;
	tymax = (m_Bounds[1-ray.m_Sign[1]].y - ray.m_Origin.y) * ray.m_InvDirection.y;
	if ( (tmin > tymax) || (tymin > tmax) )
		return false;
	if (tymin > tmin)
		tmin = tymin;
	if (tymax < tmax)
		tmax = tymax;
	tzmin = (m_Bounds[ray.m_Sign[2]].z - ray.m_Origin.z) * ray.m_InvDirection.z;
	tzmax = (m_Bounds[1-ray.m_Sign[2]].z - ray.m_Origin.z) * ray.m_InvDirection.z;
	if ( (tmin > tzmax) || (tzmin > tmax) )
		return false;
	if (tzmin > tmin)
		tmin = tzmin;
	if (tzmax < tmax)
		tmax = tzmax;
	
	distance = tmin;
	return ( (tmin < t1) && (tmax > t0) );
}

void AABBMesh::GetData(float* c1x,float* c1y, float* c1z, float* c2x,float* c2y, float* c2z){
	*c1x = m_Bounds[0].x;
	*c1y = m_Bounds[0].y;
	*c1z = m_Bounds[0].z;
	*c2x = m_Bounds[1].x;
	*c2y = m_Bounds[1].y;
	*c2z = m_Bounds[1].z;
}
